#ifndef WAVELET_HEADER
#define WAVELET_HEADER

#include <cmath>
#include <cstdio>
#include <vector>

class Wavelet2D {

public:
	void SetImageDataPtr( float * img, int instride, int inwidth, int inheight ) {
		imgData = img;
		width = inwidth;
		height = inheight;
		stride = instride;
	}

	void ProcessHaar2DStandard() {
		for (int ycoord = 0; ycoord < height; ++ycoord){
			ProcessHaar1DStandardRow(ycoord);
		}
	}

private:
	float X( int pix_x ) {
		return (float)pix_x/(float)width;
	}

	float Y( int pix_y) {
		return (float)pix_y/(float)height;
	}

	void Set1DScaleFunc( float (* inScaleFunc)(float) ){
		ScaleFunc1D = inScaleFunc;
	}

	void Set1DWaveletFunc( float (* inWaveletFunc)(float) ){
		WaveletFunc1D = inWaveletFunc;
	}

	float ScaleDilateCoord( float input_t, int level, int support_pt){
		return ((float)(std::pow)(2.0f, level)*input_t - (float)support_pt);
	}

	int ArrayCoord(int pix_x, int pix_y){
		return pix_y*width*stride + pix_x;
	}

	float GetData( int pix_x, int pix_y ){
		return imgData[ArrayCoord(pix_x, pix_y)];
	}

	void SetData( int pix_x, int pix_y, float data){
		imgData[ArrayCoord(pix_x, pix_y)] = data;
	}

	void ProcessHaar1DStandardRow( int yCoord ){
		float numCoeff = width;
		std::vector<float> tmpRow(width);
		while (numCoeff >= 2){
		for (int c = 0; c < stride; ++c){
			for (int i = 0; i < (numCoeff/2); ++i){
				
					int c1 = yCoord*width + 2*i + (c*width*height);
					int c2 = yCoord*width + (2*i+1) + (c*width*height);

					float coeffPair[2] = {
						this->imgData[c1], 
						this->imgData[c2]
					};

					float decompCoeff =  ( coeffPair[0] + coeffPair[1])*0.5f;
					float decompWavelet = ( coeffPair[0] - decompCoeff );
				
					tmpRow[i*2] = decompCoeff;
					tmpRow[i*2+1] = decompWavelet;

				
			}

			for (int j = 0; j < numCoeff/2; ++j){
				int d1 = ((j) + yCoord*width + (c*width*height));
				int d2 = ((numCoeff/2 + j) + yCoord*width ) + (c*width*height);

				imgData[d1] = tmpRow[j*2];
				imgData[d2] = tmpRow[j*2+1];
			}
			
		}	

			numCoeff /= 2;
		}
	}

	
	
	void ProcessHaar2DNonstandard() {
	}

private:
	float * imgData;
	int width, height;
	int stride;

	float (* ScaleFunc1D)(float);
	float (* WaveletFunc1D)(float);
};

#endif